#coding:utf-8
from django.db import models
from django.db.models import F
from pythonems.models import ISQL
import copy

class Major(ISQL):
    class Meta:
        permissions = (
            ("get_major", "Get or Search Major"),
        )
        ordering = ["pk"]
class Char(ISQL):
    class Meta:
        permissions = (
            ("get_char", "Get or Search Char"),
        )
        ordering = ["index"]
    major = models.ForeignKey(Major)
    parent = models.ForeignKey('self', null=True)
    is_kp = models.BooleanField(default=False)
    index = models.PositiveSmallIntegerField(default=1)
    # ########
    # CRUD
    # ########
    relation_dict = copy.copy(ISQL.relation_dict)
    relation_dict.update({
        "major_id": "major_id",
        "parent_id": "parent_id",
        "is_kp": "is_kp",
        "index": "index",
    })
    values_args = copy.copy(ISQL.values_args)
    values_args.extend([
        "major_id", "parent_id", "is_kp", "index",
    ])
    create_arg_list = copy.copy(ISQL.create_arg_list)
    create_arg_list.extend([
        "major_id", "parent_id", "is_kp", "index",
    ])
    update_arg_list = copy.copy(ISQL.update_arg_list)
    update_arg_list.extend([
        "parent_id", "index",
    ])
    update_forginkey_dict = {
        "parent_id": "parent"
    }
    search_arg_dict = copy.copy(ISQL.search_arg_dict)
    search_arg_dict.update({
        "major_id": "major_id",
        "parent_id": "parent_id",
        "is_kp": "is_kp",
    })
    @classmethod
    def update(cls, item_pk, kwargs):
        after = {}
        if "index" in kwargs and kwargs["index"] != None:
            after["index"] = kwargs["index"]
        if "parent_id" in kwargs and kwargs["parent_id"] != None:
            #use 0 as None
            kwargs["parent_id"] = kwargs["parent_id"] or None
            after["parent_id"] = kwargs["parent_id"]
        if after != {}:
            cls.update_father_or_index(item_pk, after)
        return super(Char, cls).update(item_pk, kwargs)
    @classmethod
    def update_father_or_index(cls, item_pk, after):
        item_obj = cls.objects.get(pk=item_pk)
        if not "parent_id" in after:
            after["parent_id"] = item_obj.parent_id
        if not "index" in after:
            after["index"] = item_obj.index
        drag = {"major_id": item_obj.major_id,
                "before_parent_id": item_obj.parent_id or 0,
                "before_index": item_obj.index,
                "after_parent_id": after["parent_id"] or 0,
                "after_index": 1 if after["index"] < 1 else after["index"], }
        #other items need to be moved
        if drag["before_parent_id"] == drag["after_parent_id"]:
            if drag["before_index"] != drag["after_index"]:
                move = -1 if drag["before_index"] < drag["after_index"] else 1
                start, end = sorted([drag["before_index"], drag["after_index"]])
                cls.objects.filter(major_id=drag["major_id"],
                                   parent_id=drag["before_parent_id"] or None,
                                   index__gte=start,
                                   index__lte=end, ).update(index=F('index') + move)
        #with different father_ID
        else:
            #from_list
            cls.objects.filter(major_id=drag["major_id"],
                               parent_id=drag["before_parent_id"] or None,
                               index__gt=drag["before_index"], ).update(index=F('index')-1)
            #aim_list
            cls.objects.filter(major_id=drag["major_id"],
                               parent_id=drag["after_parent_id"] or None,
                               index__gte=drag["after_index"], ).update(index=F('index')+1)